package com.ie.cloud.payment.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.icbc.api.DefaultIcbcClient;
import com.icbc.api.IcbcApiException;
import com.icbc.api.UiIcbcClient;
import com.icbc.api.request.BillLoadRequestV1;
import com.icbc.api.request.BillSingleModifyRequestV1;
import com.icbc.api.request.BillSingleQueryRequestV1;
import com.icbc.api.request.EpaymentBillRequestV1;
import com.icbc.api.request.PaymentDetailQueryRequestV1;
import com.icbc.api.request.RefundRequestV1;
import com.icbc.api.response.BillLoadResponseV1;
import com.icbc.api.response.BillSingleModifyResponseV1;
import com.icbc.api.response.BillSingleQueryResponseV1;
import com.icbc.api.response.PaymentDetailQueryResponseV1;
import com.icbc.api.response.RefundResponseV1;
import com.ie.cloud.payment.cache.RedisUtil;
import com.ie.cloud.payment.constants.CS;
import com.ie.cloud.payment.dto.GeneralOrderDto;
import com.ie.cloud.payment.entity.PayInterfaceDefine;
import com.ie.cloud.payment.exception.BizException;
import com.ie.cloud.payment.request.MyBillLoadRequestV1;
import com.ie.cloud.payment.request.MyBillSingleModifyRequestV1;
import com.ie.cloud.payment.request.MyBillSingleQueryRequestV1;
import com.ie.cloud.payment.request.MyEPaymentBillRequestV1;
import com.ie.cloud.payment.request.MyEPaymentRefundRequestV1;
import com.ie.cloud.payment.request.MyPaymentDetailQueryRequestV1;
import com.ie.cloud.payment.utils.StringKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static com.icbc.api.IcbcConstants.CHARSET_UTF8;
import static com.icbc.api.IcbcConstants.ENCRYPT_TYPE_AES;
import static com.icbc.api.IcbcConstants.FORMAT_JSON;
import static com.icbc.api.IcbcConstants.SIGN_TYPE_RSA2;

/**
 * Created with FR
 *
 * @Author: DQ
 * @Date: 2025/07/17/10:14
 * @Description: 描述语句
 */
@Service
@Slf4j
public class ICBCServiceImpl {


    /**
     * 缴费账单导入(RSA2方式)
     *
     * @param dto 参数
     * @param busId 订单号
     */
    BillLoadResponseV1 billLoadRequestV1(GeneralOrderDto<MyBillLoadRequestV1> dto, String busId) {
        log.info("缴费账单导入 参数信息 {},哈希值 {}", dto,dto.hashCode());
        DefaultIcbcClient client = new DefaultIcbcClient(
                dto.getAppId(),
                SIGN_TYPE_RSA2,
                dto.getSignSecret(),
                CHARSET_UTF8,
                FORMAT_JSON,
                dto.getApiGwPublicKey(),
                ENCRYPT_TYPE_AES,
                dto.getAesKey(),
                null,
                null);
        BillLoadRequestV1 request = new BillLoadRequestV1();
        String currentMethodFullPath = StringKit.getCurrentMethodFullPath();


        Object object = RedisUtil.getObject(StrUtil.join(StrUtil.COLON,CS.PAY_INTERFACE_CACHE.PAY_INTERFACE_DEFINE_CACHE,dto.getIfCode()));
        request.setServiceUrl(PayInterfaceDefine.getUrl( object, currentMethodFullPath));
        BillLoadRequestV1.BillLoadRequestV1Biz bizContent = new BillLoadRequestV1.BillLoadRequestV1Biz();
        request.setBizContent(bizContent);
        bizContent.setBatchNo(dto.getExaData().getBatchNo());//账单批次号
        bizContent.setCorpCis(dto.getExaData().getCorpCis());//企业客户编号
        bizContent.setProjectId(dto.getExaData().getProjectId());//缴费项目编号
        bizContent.setEbppFlag("");//ebpp标志 ?
        bizContent.setBillName(dto.getExaData().getBillName());//账单别名 false
        bizContent.setTotalAmt(dto.getExaData().getTotalAmt());//账单批次总金额(单位为分)
        bizContent.setTotalNum(dto.getExaData().getTotalNum());//账单批次总笔数
        bizContent.setStartNum(dto.getExaData().getStartNum());//开始导入序号（从1开始）
        bizContent.setFetchNum(dto.getExaData().getFetchNum());//本次导入笔数
        bizContent.setTotalNum(dto.getExaData().getTotalNum());//账单对象列表
        List<BillLoadRequestV1.BillLoadRequestV1BizBill> billList = new ArrayList<>();
        BillLoadRequestV1.BillLoadRequestV1BizBill bill1 = new BillLoadRequestV1.BillLoadRequestV1BizBill();
        bill1.setBillNo(1);//账单序号
        bill1.setBusiCode(busId);//缴费编号
        bill1.setBillCaeseDate(dto.getExaData().getBillCaeseDate());//明细失效时间
        bill1.setMobile(dto.getExaData().getMobile());//
        bill1.setBillDate(dto.getExaData().getBillDate());//出账日期，YYYY-MM-DD
        bill1.setBillAmount(dto.getExaData().getBillAmount());//账单金额（单位为分）
        billList.add(bill1);
        bizContent.setBillList(billList);
        BillLoadResponseV1 response;
        log.info("缴费账单导入 调用参数 {}", JSON.toJSONString(request));
        try {
            response = client.execute(request, busId);
            if (response.isSuccess()) {
                // 业务成功处理
                log.info("返回结果：{}" , JSON.toJSONString(response));
            } else {
                // 失败
                log.error("返回结果：{}" , JSON.toJSONString(response));
            }
            return response;
        } catch (IcbcApiException e) {
            log.error("调用异常！{}", e.getMessage());
            throw new BizException(e.getMessage());
        }
    }


    /**
     * 缴费大厅账单(RSA2方式)
     */
    String EPaymentBillRequestV1Function(GeneralOrderDto<MyEPaymentBillRequestV1> dto,String busId) {

        log.info("缴费大厅账单 参数信息 {}", dto);

        UiIcbcClient client = new UiIcbcClient(
                dto.getAppId(),
                SIGN_TYPE_RSA2,
                dto.getSignSecret(),
                CHARSET_UTF8,
                ENCRYPT_TYPE_AES,
                dto.getAesKey());

        EpaymentBillRequestV1 request = new EpaymentBillRequestV1();

        String currentMethodFullPath = StringKit.getCurrentMethodFullPath();


        Object object = RedisUtil.getObject(StrUtil.join(StrUtil.COLON,CS.PAY_INTERFACE_CACHE.PAY_INTERFACE_DEFINE_CACHE,dto.getIfCode()));

        request.setServiceUrl(PayInterfaceDefine.getUrl( object, currentMethodFullPath));
        EpaymentBillRequestV1.EpaymentBillRequestV1Biz bizContent = new EpaymentBillRequestV1.EpaymentBillRequestV1Biz();
        bizContent.setComputeId(dto.getExaData().getComputeId());
        bizContent.setAreaCode("0512");//地区信息，上送工行4位地区码，默认值北京0200
        bizContent.setUserId("1");
        bizContent.setPayitemCode(dto.getExaData().getProjectId());
        bizContent.setCustomInfo(String.format("busiCode=%s||openId=%s",busId,"openId123"));
        request.setBizContent(bizContent);

        log.info("缴费大厅账单 调用参数 {}", JSON.toJSONString(request));

        try {

            String htmlContent = client.buildPostForm(request,busId);

            log.info("缴费大厅账单 返回结果 {}", htmlContent);

            return htmlContent;

        }catch (Exception e) {
            log.error("缴费大厅账单 生成失败 {}",e.getMessage());
            throw new BizException(e.getMessage());
        }
    }


    /**
     * 缴费平台单笔账单查询
     * @param dto 账单查询参数
     */
    BillSingleQueryResponseV1 EPayBillSingleQuery(GeneralOrderDto<MyBillSingleQueryRequestV1> dto) {
        log.info("缴费平台单笔账单查询 参数信息 {},哈希值 {}", dto,dto.hashCode());
        DefaultIcbcClient client = new DefaultIcbcClient(
                dto.getAppId(),
                SIGN_TYPE_RSA2,
                dto.getSignSecret(),
                CHARSET_UTF8,
                FORMAT_JSON,
                dto.getApiGwPublicKey(),
                ENCRYPT_TYPE_AES,
                dto.getAesKey(),
                null,
                null);

        BillSingleQueryRequestV1 request = new BillSingleQueryRequestV1();
        String currentMethodFullPath = StringKit.getCurrentMethodFullPath();


        Object object = RedisUtil.getObject(StrUtil.join(StrUtil.COLON,CS.PAY_INTERFACE_CACHE.PAY_INTERFACE_DEFINE_CACHE,dto.getIfCode()));
        request.setServiceUrl(PayInterfaceDefine.getUrl( object, currentMethodFullPath));
        BillSingleQueryRequestV1.BillSingleQueryRequestV1Biz bizContent = new BillSingleQueryRequestV1.BillSingleQueryRequestV1Biz();
        request.setBizContent(bizContent);
        bizContent.setCorpCis(dto.getExaData().getCorpCis());
        bizContent.setProjectId(dto.getExaData().getProjectId());
        bizContent.setBatchNo(dto.getExaData().getBatchNo());
        bizContent.setBillNo(dto.getExaData().getBillNo());
        BillSingleQueryResponseV1 response;

        try {
            log.info("缴费平台单笔账单查询 调用参数 {}", JSON.toJSONString(request));
            response = client.execute(request);
            if (response.isSuccess()) {

                log.info("缴费平台单笔账单查询 成功 {}", JSON.toJSONString(response));
            }else {
                log.info("缴费平台单笔账单查询 失败 {}", JSON.toJSONString(response));
            }
            return response;
        } catch (IcbcApiException e) {
            log.error("缴费平台单笔账单查询 调用异常！{}", e.getMessage());
            throw new BizException("缴费平台单笔账单查询 调用异常!");
        }
    }


    /**
     * 缴费明细查询(RSA2方式)
     */
    public PaymentDetailQueryResponseV1 EPaymentDetailQueryRequestV1Function(
            GeneralOrderDto<MyPaymentDetailQueryRequestV1> dto) {
        log.info("缴费明细查询 参数信息 {}", dto);
        DefaultIcbcClient client = new DefaultIcbcClient(
                dto.getAppId(),
                SIGN_TYPE_RSA2,
                dto.getSignSecret(),
                CHARSET_UTF8,
                FORMAT_JSON,
                dto.getApiGwPublicKey(),
                ENCRYPT_TYPE_AES,
                dto.getAesKey(),
                null,
                null);
        PaymentDetailQueryRequestV1 request = new PaymentDetailQueryRequestV1();
        // 接口地址
        String currentMethodFullPath = StringKit.getCurrentMethodFullPath();


        Object object = RedisUtil.getObject(StrUtil.join(StrUtil.COLON,CS.PAY_INTERFACE_CACHE.PAY_INTERFACE_DEFINE_CACHE,dto.getIfCode()));
        request.setServiceUrl(PayInterfaceDefine.getUrl(object, currentMethodFullPath));
        PaymentDetailQueryRequestV1.PaymentDetailQueryRequestV1Biz bizContent = new PaymentDetailQueryRequestV1.PaymentDetailQueryRequestV1Biz();
        request.setBizContent(bizContent);
        bizContent.setCorpCis(dto.getExaData().getCorpCis());//集团业务编号（与busi_code必须输入一项）(项目唯一)（改）
        bizContent.setBusiCode(dto.getExaData().getBusiCode());//缴费编号（与corp_cis必须输入一项），如果传入busiCode，查的是该笔busiCode缴费结果
        bizContent.setProjectId(dto.getExaData().getProjectId());//缴费项目编号（必输）（项目唯一）（改）
        bizContent.setQueryType(dto.getExaData().getQueryType());//2—到账查询 1-当日查询
        bizContent.setTrxDate(dto.getExaData().getTrxDate());//交易日期（必输）
//        bizContent.setAppUserId("1");
        bizContent.setTrxTimeStart(dto.getExaData().getTrxTimeStart());//开始交易时间 当日查询必输
        bizContent.setTrxTimeEnd(dto.getExaData().getTrxTimeEnd());//trx_time_end-结束交易时间  当日查询必输
        bizContent.setCurPage(dto.getExaData().getCurPage());//当前页（从0开始）（必输）
        bizContent.setFetchNum(dto.getExaData().getFetchNum());//一次查询最大记录数（不能超过100）（必输）
        bizContent.setQueryDim(dto.getExaData().getQueryDim());

        try {
            log.info("缴费明细查询 调用参数 {}", JSON.toJSONString(request));
            PaymentDetailQueryResponseV1 response = client.execute(request, UUID.randomUUID().toString());

            if (response.isSuccess()) {
                log.info("缴费明细查询 成功 {}", JSON.toJSONString(response));
            }else {
                log.info("缴费明细查询 错误 {}", JSON.toJSONString(response));
            }

            return response;

        }catch (IcbcApiException e) {
            log.error("缴费明细查询 调用异常！{}", e.getMessage());
            throw new BizException("缴费明细查询 调用异常!");
        }
    }

    /**
     * 缴费平台退费(RSA2方式)
     */
    @SuppressWarnings("un")
    RefundResponseV1 EPaymentRefundRequestV1Function(GeneralOrderDto<MyEPaymentRefundRequestV1> dto, String busId) {
        log.info("缴费平台退费 参数信息 {}", dto);

        DefaultIcbcClient client = new DefaultIcbcClient(dto.getAppId(),
                SIGN_TYPE_RSA2,
                dto.getSignSecret(),
                CHARSET_UTF8,
                FORMAT_JSON,
                dto.getApiGwPublicKey(),
                ENCRYPT_TYPE_AES,
                dto.getAesKey(),
                null,
                null);
        RefundRequestV1 request = new RefundRequestV1();
        // 接口地址
        String currentMethodFullPath = StringKit.getCurrentMethodFullPath();


        Object object = RedisUtil.getObject(StrUtil.join(StrUtil.COLON,CS.PAY_INTERFACE_CACHE.PAY_INTERFACE_DEFINE_CACHE,dto.getIfCode()));
        request.setServiceUrl(PayInterfaceDefine.getUrl( object, currentMethodFullPath));
        RefundRequestV1.RefundRequestV1Biz bizContent = new RefundRequestV1.RefundRequestV1Biz();
        request.setBizContent(bizContent);
        bizContent.setCorpCis(dto.getExaData().getCorpCis());//集团业务编号（必输）(项目唯一)（改）
        bizContent.setProjectId(dto.getExaData().getProjectId());//缴费项目编号（必输）（项目唯一）（改）

        bizContent.setRefundSerialno(dto.getExaData().getRefundSerialno());//退费申请编号(必输)（随便编一个系统内唯一即可）
        bizContent.setRefundDate(dto.getExaData().getRefundDate());//退费日期（YYYY-MM-DD）(必输)（测试环境下填当前日期）
        bizContent.setOriTransSeq(dto.getExaData().getOriTransSeq());//原缴费交易流水号(必输)缴费明细查询返回的trans_ref_guid
        bizContent.setOriPayDate(dto.getExaData().getOriPayDate());//原缴费日期（YYYY-MM-DD）(必输)
        bizContent.setRefundAmount(new BigDecimal(dto.getExaData().getRefundAmount()));//退费金额（单位分）(必输)
        bizContent.setApprMark(dto.getExaData().getAuditRemark());//审核意见(必输)



        try {
            log.info("缴费平台退费 调用参数 {}", JSON.toJSONString(request));
            RefundResponseV1 response = client.execute(request, dto.getExaData().getRefundSerialno());
            if (response.isSuccess()) {
                // 业务成功处理
                log.info("缴费平台退费 成功 {}", JSON.toJSONString(response));
            } else {
                // 失败
                log.info("缴费平台退费 失败 {}", JSON.toJSONString(response));
            }
            return response;
        } catch (Exception e) {
            log.error("缴费平台退费 调用异常！{}", e.getMessage());
            throw new BizException("缴费平台退费 调用异常!");
        }
    }


    /**
     * 单笔修改
     */
    BillSingleModifyResponseV1 EPayBillSingleModify(GeneralOrderDto<MyBillSingleModifyRequestV1> dto, String busId) {
        log.info("单笔修改 参数信息 {},哈希值 {}", dto,dto.hashCode());

        DefaultIcbcClient client = new DefaultIcbcClient(
                dto.getAppId(),
                SIGN_TYPE_RSA2,
                dto.getSignSecret(),
                CHARSET_UTF8,
                FORMAT_JSON,
                dto.getApiGwPublicKey(),
                ENCRYPT_TYPE_AES,
                dto.getAesKey(),
                null,
                null);


        BillSingleModifyRequestV1 request = new BillSingleModifyRequestV1();

        String currentMethodFullPath = StringKit.getCurrentMethodFullPath();


        Object object = RedisUtil.getObject(StrUtil.join(StrUtil.COLON,CS.PAY_INTERFACE_CACHE.PAY_INTERFACE_DEFINE_CACHE,dto.getIfCode()));
        request.setServiceUrl(PayInterfaceDefine.getUrl( object, currentMethodFullPath));

        BillSingleModifyRequestV1.BillSingleModifyRequestV1Biz bizContent = new BillSingleModifyRequestV1.BillSingleModifyRequestV1Biz();

        request.setBizContent(bizContent);

        bizContent.setCorpCis(dto.getExaData().getCorpCis());
        bizContent.setProjectId(dto.getExaData().getProjectId());
        bizContent.setBatchNo("1");
        bizContent.setBillNo(busId);//账单别名,确定是否为busiCode
        bizContent.setBillCaeseDate(dto.getExaData().getBillCaeseDate());//明细失效时间
        bizContent.setBillAmount(new BigDecimal(dto.getExaData().getBillAmount()));//账单金额,单位分

        BillSingleModifyResponseV1 response;

        try {
            log.info("单笔修改 调用参数 {}", JSON.toJSONString(request));
            response = client.execute(request);
            if (response.isSuccess()) {

                log.info("单笔修改 成功 {}", JSON.toJSONString(response));
            }else {
                log.info("单笔修改 失败 {}", JSON.toJSONString(response));
            }
            return response;
        } catch (IcbcApiException e) {
            log.error("单笔修改 调用异常！{}", e.getMessage());
            throw new BizException(e.getErrCode(),e.getMessage());
        }

    }


}
